#ifndef __MM_MM_H__
#define __MM_MM_H__

/**
 * Linux kernel virtual memory manager primitives.
 * The idea being to have a "virtual" mm in the same way
 * we have a virtual fs - giving a cleaner interface to the
 * mm details, and allowing different kinds of memory mappings
 * (from shared memory to executable loading to arbitrary
 * mmap() functions).
 */

/*
 * This struct defines a memory VMM memory area. There is one of these
 * per VM-area/task.  A VM area is any part of the process virtual memory
 * space that has a special rule for the page-fault handlers (ie a shared
 * library, the executable area etc).
 */
struct vm_area_struct {
  struct mm_struct* vm_mm;
  u32 vm_start;
  u32 vm_end;

  struct vm_area_struct *vm_next;
  pgprot_t vm_page_prot;
  u32 vm_flags;

  struct rb_node vm_rb;

  union {
    struct {
      struct list_head first;
      void *parent;
      struct vm_area_struct *head;
    } vm_set;

    struct raw_prio_tree_node prio_tree_node;
  } shared;
};

struct vm_operations_struct {
  void (*open)(struct vm_area_struct *area);
  void (*close)(struct vm_area_struct *area);
  struct page* (*nopage)(struct vm_area_struct *area, u32 address,
                         int *type);
  int (*populate)(struct vm_area_struct *area, u32 address,
                  u32 len, pgprot_t prot, u32 pgoff, int nonblock);
  int (*set_policy)(struct vm_area_struct *area, struct mempolicy *new);
  struct mempolicy *(*get_policy)(struct vm_area_struct *vma, u32 addr);
};

typedef u32 page_flags_t;

struct page {
  page_flags_t flags;

  atomic_t _count;
  atomic_t _mapcount;

  u32 private;
  struct address_space *mapping;

  pgoff_t index;
  struct list_head lru;
};

#endif  // o__MM_MM_H__
